package _0_3_打家劫舍

/*
*
原题链接:
https://leetcode.cn/problems/house-robber/

198. 打家劫舍
你是一个专业的小偷，计划偷窃沿街的房屋。每间房内都藏有一定的现金，
影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统，如果两间相邻的房屋在同一晚上被小偷闯入，系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组，计算你 不触动警报装置的情况下 ，一夜之内能够偷窃到的最高金额。

示例 1：
输入：[1,2,3,1]
输出：4
解释：偷窃 1 号房屋 (金额 = 1) ，然后偷窃 3 号房屋 (金额 = 3)。
  - 偷窃到的最高金额 = 1 + 3 = 4 。

示例 2：
输入：[2,7,9,3,1]
输出：12
解释：偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9)，接着偷窃 5 号房屋 (金额 = 1)。
  - 偷窃到的最高金额 = 2 + 9 + 1 = 12 。

思路:
当前房间偷还是不偷, 取决于前一个房间和前两个房间的状态
如果前一个房间被偷了, 那么当前房间是一定不能被偷的, 如果前两个房间被偷了, 那么当前房间就是可以被偷的

一. dp数组含义
  - 考虑下标i所偷的最大的总金额 dp[i]
    返回最终结果 dp[nums.size() - 1]

二. 递推公式

  - 如果偷i房间, 那么i-1房间是一定不能偷的, 所以需要dp[i-2]加上当前i房间的金币数量
    偷i房间: dp[i-2] + nums[j]

    如果不偷i房间, 那么只需要考虑i-1之前的房间
*/
func rob1(nums []int) int {

	//1.特殊情况判断
	if len(nums) == 0 { //如果没有房间可偷, 直接返回0即可
		return 0
	}
	if len(nums) == 1 { //如果只有一间房可偷, 那么直接返回房间0的值即可
		return nums[0]
	}

	//2.声明dp数组
	dp := make([]int, len(nums))
	dp[0] = nums[0]
	dp[1] = max(nums[0], nums[1])

	for i := 2; i < len(nums); i++ {
		dp[i] = max(nums[i]+dp[i-2], dp[i-1])
	}

	return dp[len(nums)-1]
}
